package com.kexio.user.service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;

import com.kexio.user.entity.User;

/**
 * 用户服务接口
 * 
 * 提供用户管理的核心业务逻辑，包括：
 * - 用户CRUD操作
 * - 用户认证信息管理
 * - 用户权限聚合
 * - 用户状态管理
 * - 多租户数据隔离
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
public interface UserService {
    
    // ==================== 基础CRUD操作 ====================
    
    /**
     * 创建用户
     * 
     * @param user 用户信息
     * @return 创建的用户信息
     */
    User createUser(User user);
    
    /**
     * 根据ID更新用户信息
     * 
     * @param userId 用户ID
     * @param user 更新的用户信息
     * @return 更新后的用户信息
     */
    User updateUser(String userId, User user);
    
    /**
     * 根据ID删除用户（逻辑删除）
     * 
     * @param userId 用户ID
     * @return 是否删除成功
     */
    boolean deleteUser(String userId);
    
    /**
     * 根据ID查询用户信息
     * 
     * @param userId 用户ID
     * @return 用户信息
     */
    User getUserById(String userId);
    
    /**
     * 根据用户名查询用户信息
     * 
     * @param username 用户名
     * @return 用户信息
     */
    User getUserByUsername(String username);
    
    /**
     * 根据手机号查询用户信息
     * 
     * @param phone 手机号
     * @return 用户信息
     */
    User getUserByPhone(String phone);
    
    /**
     * 根据邮箱查询用户信息
     * 
     * @param email 邮箱
     * @return 用户信息
     */
    User getUserByEmail(String email);
    
    // ==================== 用户列表查询 ====================
    
    /**
     * 获取所有用户列表（不分页）
     * 注意：此方法可能返回大量数据，建议仅用于特定场景（如获取在线用户）
     * 
     * @return 所有用户列表
     */
    List<User> getAllUsers();
    
    /**
     * 分页查询用户列表
     * 
     * @param current 当前页码
     * @param size 每页大小
     * @return 分页用户列表
     */
    com.baomidou.mybatisplus.extension.plugins.pagination.Page<User> getUserPage(Long current, Long size);
    
    /**
     * 根据条件查询用户列表
     * 
     * @param username 用户名（模糊查询）
     * @param phone 手机号（模糊查询）
     * @param email 邮箱（模糊查询）
     * @param status 用户状态
     * @param deptId 部门ID
     * @return 用户列表
     */
    List<User> getUserList(String username, String phone, String email, String status, String deptId);
    
    /**
     * 查询部门下的用户列表
     * 
     * @param deptId 部门ID
     * @return 用户列表
     */
    List<User> getUsersByDept(String deptId);
    
    /**
     * 查询多个部门下的用户列表
     * 
     * @param deptIds 部门ID列表
     * @return 用户列表
     */
    List<User> getUsersByDepts(List<String> deptIds);
    
    /**
     * 根据数据权限查询用户列表
     * 
     * @param currentUserId 当前用户ID
     * @param dataScopeType 数据权限类型
     * @param deptIds 部门ID列表
     * @return 用户列表
     */
    List<User> getUsersInDataScope(String currentUserId, String dataScopeType, List<String> deptIds);
    
    // ==================== 用户认证相关 ====================
    
    /**
     * 验证用户登录
     * 
     * @param loginAccount 登录账号（用户名/手机号/邮箱）
     * @param password 密码
     * @param tenantId 租户ID
     * @return 用户信息（验证成功）或 null（验证失败）
     */
    User authenticate(String loginAccount, String password, String tenantId);
    
    /**
     * 更新用户密码
     * 
     * @param userId 用户ID
     * @param oldPassword 旧密码
     * @param newPassword 新密码
     * @return 是否更新成功
     */
    boolean updatePassword(String userId, String oldPassword, String newPassword);
    
    /**
     * 重置用户密码
     * 
     * @param userId 用户ID
     * @param newPassword 新密码
     * @param operatorId 操作者ID
     * @return 是否重置成功
     */
    boolean resetPassword(String userId, String newPassword, Long operatorId);
    
    // ==================== 用户状态管理 ====================
    
    /**
     * 更新用户最后登录时间
     * 
     * @param userId 用户ID
     * @param lastLoginTime 最后登录时间
     * @return 是否更新成功
     */
    boolean updateLastLoginTime(String userId, LocalDateTime lastLoginTime);
    
    /**
     * 增加用户密码错误次数
     * 
     * @param userId 用户ID
     * @return 当前错误次数
     */
    int incrementPasswordErrorCount(String userId);
    
    /**
     * 清零用户密码错误次数
     * 
     * @param userId 用户ID
     * @return 是否清零成功
     */
    boolean clearPasswordErrorCount(String userId);
    
    /**
     * 锁定用户账户
     * 
     * @param userId 用户ID
     * @param lockMinutes 锁定分钟数
     * @return 是否锁定成功
     */
    boolean lockUser(String userId, int lockMinutes);
    
    /**
     * 解锁用户账户
     * 
     * @param userId 用户ID
     * @return 是否解锁成功
     */
    boolean unlockUser(String userId);
    
    /**
     * 检查用户是否被锁定
     * 
     * @param user 用户信息
     * @return 是否被锁定
     */
    boolean isUserLocked(User user);
    
    // ==================== 用户权限聚合 ====================
    
    /**
     * 获取用户的所有权限编码
     * 
     * @param userId 用户ID
     * @return 权限编码列表
     */
    List<String> getUserPermissions(String userId);
    
    /**
     * 获取用户的所有角色ID
     * 
     * @param userId 用户ID
     * @return 角色ID列表
     */
    List<String> getUserRoles(String userId);
    
    /**
     * 获取用户的菜单列表
     * 
     * @param userId 用户ID
     * @return 菜单列表
     */
    List<com.kexio.user.entity.Menu> getUserMenus(String userId);
    
    /**
     * 获取用户的数据权限范围
     * 
     * @param userId 用户ID
     * @return 数据权限上下文
     */
    Object getUserDataScope(String userId);
    
    // ==================== 用户角色管理 ====================
    
    /**
     * 为用户分配角色
     * 
     * @param userId 用户ID
     * @param roleIds 角色ID列表
     * @param operatorId 操作者ID
     * @return 是否分配成功
     */
    boolean assignRoles(String userId, List<String> roleIds, Long operatorId);
    
    /**
     * 移除用户的角色
     * 
     * @param userId 用户ID
     * @param roleIds 角色ID列表
     * @return 是否移除成功
     */
    boolean removeRoles(String userId, List<String> roleIds);
    
    /**
     * 同步用户的角色（先清除再分配）
     * 
     * @param userId 用户ID
     * @param roleIds 新的角色ID列表
     * @param operatorId 操作者ID
     * @return 是否同步成功
     */
    boolean syncRoles(String userId, List<String> roleIds, Long operatorId);
    
    // ==================== 用户权限版本管理 ====================
    
    /**
     * 更新用户权限版本
     * 
     * @param userId 用户ID
     * @param permVersion 权限版本
     * @return 是否更新成功
     */
    boolean updatePermVersion(String userId, Long permVersion);
    
    /**
     * 获取用户当前权限版本
     * 
     * @param userId 用户ID
     * @return 权限版本
     */
    Long getUserPermVersion(String userId);
    
    // ==================== 统计查询 ====================
    
    /**
     * 统计用户总数
     * 
     * @return 用户总数
     */
    Long countUsers();
    
    /**
     * 统计活跃用户数量（最近30天登录过）
     * 
     * @return 活跃用户数
     */
    Long countActiveUsers();
    
    /**
     * 统计总用户数量
     * 
     * @return 总用户数量
     */
    Long countTotalUsers();
    
    /**
     * 统计总租户数量
     * 
     * @return 总租户数量
     */
    Long countTotalTenants();
    
    /**
     * 统计活跃租户数量
     * 
     * @return 活跃租户数量
     */
    Long countActiveTenants();
    
    /**
     * 获取各租户用户数统计
     * 
     * @return 租户ID -> 用户数的映射
     */
    java.util.Map<String, Long> getTenantUserCounts();
    
    // ==================== 数据验证 ====================
    
    /**
     * 检查用户名是否存在
     * 
     * @param username 用户名
     * @param excludeUserId 排除的用户ID（用于更新时检查）
     * @return 是否存在
     */
    boolean existsByUsername(String username, String excludeUserId);
    
    /**
     * 检查手机号是否存在
     * 
     * @param phone 手机号
     * @param excludeUserId 排除的用户ID（用于更新时检查）
     * @return 是否存在
     */
    boolean existsByPhone(String phone, String excludeUserId);
    
    /**
     * 检查邮箱是否存在
     * 
     * @param email 邮箱
     * @param excludeUserId 排除的用户ID（用于更新时检查）
     * @return 是否存在
     */
    boolean existsByEmail(String email, String excludeUserId);
    
    // ==================== Controller层扩展方法 ====================
    
    /**
     * 创建用户（DTO版本）
     * 
     * @param request 创建用户请求
     * @return 创建的用户信息
     */
    User createUser(com.kexio.user.dto.UserDTO request);
    
    /**
     * 更新用户（DTO版本）
     * 
     * @param userId 用户ID
     * @param request 更新用户请求
     * @return 更新的用户信息
     */
    User updateUser(String userId, com.kexio.user.dto.UserDTO request);
    
    /**
     * 分页查询用户（DTO版本）
     * 
     * @param queryRequest 查询请求（UserDTO已继承PageQuery）
     * @return 分页结果
     */
    com.kexio.common.dto.PageResponse<User> queryUsers(com.kexio.user.dto.UserDTO queryRequest);
    
    /**
     * 更新用户状态
     * 
     * @param userId 用户ID
     * @param status 新状态
     * @return 是否更新成功
     */
    boolean updateUserStatus(String userId, Integer status);
    
    /**
     * 重置用户密码（简化版本）
     * 
     * @param userId 用户ID
     * @return 新密码
     */
    String resetUserPassword(String userId);
    
    /**
     * 导出用户数据
     * 
     * @param queryRequest 查询条件（UserDTO已继承PageQuery）
     * @param response HTTP响应
     */
    void exportUsers(com.kexio.user.dto.UserDTO queryRequest, 
                    jakarta.servlet.http.HttpServletResponse response);
    
    /**
     * 导入用户数据
     * 
     * @param file Excel文件
     * @param updateSupport 是否更新已存在数据
     * @return 导入结果统计
     */
    java.util.Map<String, Object> importUsers(org.springframework.web.multipart.MultipartFile file, Boolean updateSupport);
    
    /**
     * 下载用户导入模板
     * 
     * @param response HTTP响应
     */
    void downloadImportTemplate(jakarta.servlet.http.HttpServletResponse response);
    
    /**
     * 批量删除用户
     * 
     * @param userIds 用户ID列表
     * @return 删除的用户数量
     */
    int batchDeleteUsers(List<String> userIds);
    
    /**
     * 批量更新用户状态
     * 
     * @param userIds 用户ID列表
     * @param status 状态值（1-启用，0-禁用）
     * @return 更新的用户数量
     */
    int batchUpdateUserStatus(List<String> userIds, Integer status);
    
    /**
     * 封禁用户
     * 
     * @param userId 用户ID
     * @param reason 封禁原因
     * @param banDays 封禁天数，-1表示永久封禁
     * @return 是否成功
     */
    boolean banUser(String userId, String reason, int banDays);
    
    /**
     * 解封用户
     * 
     * @param userId 用户ID
     * @return 是否成功
     */
    boolean unbanUser(String userId);
    
    /**
     * 获取用户统计信息
     * 
     * @return 统计信息
     */
    com.kexio.user.dto.UserStatistics getUserStatistics();
    
    // ==================== 内部认证接口 ====================
    
    /**
     * 根据用户名获取用户认证信息（供框架内部使用）
     * 
     * @param username 用户名
     * @param tenantId 租户ID
     * @return 用户认证信息
     */
    com.kexio.auth.dto.UserAuthInfo getUserAuthInfo(String username);
    
    /**
     * 根据用户ID获取用户认证信息（供框架内部使用）
     * 
     * @param userId 用户ID
     * @param tenantId 租户ID
     * @return 用户认证信息
     */
    com.kexio.auth.dto.UserAuthInfo getUserAuthInfoById(String userId);
    
    /**
     * 通知用户权限变更（清除缓存、更新版本等）
     * 
     * @param userId 用户ID
     * @param tenantId 租户ID
     * @param reason 变更原因
     */
    void notifyUserPermissionChanged(String userId, String tenantId, String reason);
    
    /**
     * 批量重算并写入用户的角色与权限投影（管道化）。
     * 适用于角色/权限大范围变更后的重建场景。
     *
     * @param tenantId 租户ID
     * @param userIds  需要重算的用户ID列表
     * @param reason   变更原因/审计备注
     */
    void rebuildUsersProjection(java.util.List<String> userIds, String reason);
    
    // ==================== JWT权限同步支持方法 ====================
    
    /**
     * 查找拥有指定权限的用户ID集合（用于JWT权限同步）
     * 
     * @param permissionCode 权限代码
     * @return 用户ID集合
     */
    Set<String> findUsersByPermission(String permissionCode);
    
    /**
     * 查找拥有指定角色的用户ID集合（用于JWT权限同步）
     * 
     * @param roleCode 角色代码
     * @return 用户ID集合
     */
    Set<String> findUsersByRole(String roleCode);
    
}
